package com.woniuxy.yoga.notice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.statedata.AdminState;
import com.woniuxy.yoga.notice.client.AdminClient;
import com.woniuxy.yoga.notice.dao.model.SystemNotice;
import com.woniuxy.yoga.notice.dao.mapper.SystemNoticeMapper;
import com.woniuxy.yoga.notice.model.dto.adminaccount.AdminByAccountIdDTO;
import com.woniuxy.yoga.notice.model.dto.systemnotice.SearchSystemNoticeDTO;
import com.woniuxy.yoga.notice.model.dto.systemnotice.SystemNoticeDTO;
import com.woniuxy.yoga.notice.model.exception.NoticeException;
import com.woniuxy.yoga.notice.model.exception.NoticeExceptionCode;
import com.woniuxy.yoga.notice.model.param.systemnotice.ListAllSystemNoticeParam;
import com.woniuxy.yoga.notice.model.param.systemnotice.PublishSystemNoticeParam;
import com.woniuxy.yoga.notice.service.SystemNoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.ibatis.ognl.Evaluation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class SystemNoticeServiceImpl extends ServiceImpl<SystemNoticeMapper, SystemNotice> implements SystemNoticeService {

    @Autowired
    private AdminClient adminClient;
    @Autowired
    private SystemNoticeMapper systemNoticeMapper;

    /**
     * 管理员发布公告
     * @param param
     */
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void publishSystemNotice(PublishSystemNoticeParam param) {
        //查询管理员账号是否存在 状态是否正常
        Result<AdminByAccountIdDTO> adminResult = adminClient.selAdminByAccountId(param.getAccountId());
        if (adminResult.getCode()!=200) {
            throw new NoticeException(adminResult.getCode(),adminResult.getMessage());
        }
        AdminByAccountIdDTO admin = adminResult.getData();
        //将传入数据赋值到实体对象上
        SystemNotice systemNotice = BeanUtil.toBean(param, SystemNotice.class);
        systemNotice.setAccountName(admin.getAccountName());
        systemNotice.setNoticeState(AdminState.SYSTEM_NOTICE_PUBLISHED);
        systemNotice.setPublishDate(DateUtil.format(new Date(System.currentTimeMillis()), "yyyy-MM-dd HH:mm:ss"));
        //插入到数据库中
        systemNoticeMapper.insert(systemNotice);
    }

    /**
     * 按条件分页查询公告
     * @param param
     * @return
     */
    @Override
    public PageInfo listAllSystemNotice(ListAllSystemNoticeParam param) {
        LambdaQueryWrapper<SystemNotice> wrapper = new LambdaQueryWrapper<>();
        //开始拼接条件
        if (param.getNoticeState()!=null) {
            wrapper.eq(SystemNotice::getNoticeState,param.getNoticeState());
        }
        //开始分页
        Page<SystemNotice> page = new Page<>(param.getCurrent() == null ? 1 : param.getCurrent(), param.getSize() == null ? 5 : param.getSize());
        systemNoticeMapper.selectPage(page, wrapper);
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        ArrayList<SearchSystemNoticeDTO> dtos = new ArrayList<SearchSystemNoticeDTO>();
        for (SystemNotice systemNotice : page.getRecords()) {
            SearchSystemNoticeDTO searchSystemNoticeDTO = BeanUtil.toBean(systemNotice, SearchSystemNoticeDTO.class);
            dtos.add(searchSystemNoticeDTO);
        }
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(dtos);
        return pageInfo;
    }

    /**
     * 查询最新一条正常的公告
     * @return
     */
    @Override
    public SystemNoticeDTO loadLastSystemNotice() {
        //查询全部已发布的公告
        LambdaQueryWrapper<SystemNotice> wrapper = new LambdaQueryWrapper<SystemNotice>()
                .eq(SystemNotice::getNoticeState,AdminState.SYSTEM_NOTICE_PUBLISHED);
        List<SystemNotice> systemNotices = systemNoticeMapper.selectList(wrapper);
        //利用lambda表达式过滤出最晚发布的公告信息
        SystemNotice systemNotice = systemNotices.stream()
                .max(Comparator.comparing(o ->
                        LocalDateTime.parse(o.getPublishDate(),
                                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))))
                .orElse(null);
        //转换类型
        SystemNoticeDTO systemNoticeDTO = BeanUtil.toBean(systemNotice, SystemNoticeDTO.class);
        return systemNoticeDTO;
    }

    /**
     * 管理员停用系统公告
     * @param systemNoticeId
     * @param accountId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableSystemNotice(Integer systemNoticeId, Integer accountId) {
        //查询管理员账号是否存在 状态是否正常
        Result<AdminByAccountIdDTO> adminResult = adminClient.selAdminByAccountId(accountId);
        if (adminResult.getCode()!=200) {
            throw new NoticeException(adminResult.getCode(),adminResult.getMessage());
        }
        //查询当前公告是否存在
        SystemNotice systemNotice = systemNoticeMapper.selectById(systemNoticeId);
        if (systemNotice==null) {
            throw new NoticeException(NoticeExceptionCode.NOTICE_EXCEPTION_CODE_SYSTEMNOTICE_NOTEXITS);
        }
        //查询当前公告状态是否是发布状态
        if (systemNotice.getNoticeState()!= AdminState.SYSTEM_NOTICE_PUBLISHED) {
            throw new NoticeException(NoticeExceptionCode.NOTICE_EXCEPTION_CODE_NOTICESTATE_ERROR);
        }
        //修改公告状态
        systemNotice.setNoticeState(AdminState.SYSTEM_NOTICE_NOPUBLISH);
        systemNoticeMapper.updateById(systemNotice);
    }
    /**
     * 管理员启用系统公告
     * @param systemNoticeId
     * @param accountId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void normalSystemNotice(Integer systemNoticeId, Integer accountId) {
        //查询管理员账号是否存在 状态是否正常
        Result<AdminByAccountIdDTO> adminResult = adminClient.selAdminByAccountId(accountId);
        if (adminResult.getCode()!=200) {
            throw new NoticeException(adminResult.getCode(),adminResult.getMessage());
        }
        //查询当前公告是否存在
        SystemNotice systemNotice = systemNoticeMapper.selectById(systemNoticeId);
        if (systemNotice==null) {
            throw new NoticeException(NoticeExceptionCode.NOTICE_EXCEPTION_CODE_SYSTEMNOTICE_NOTEXITS);
        }
        //查询当前公告状态是否是未发布状态
        if (systemNotice.getNoticeState()!= AdminState.SYSTEM_NOTICE_NOPUBLISH) {
            throw new NoticeException(NoticeExceptionCode.NOTICE_EXCEPTION_CODE_NOTICESTATE_ERROR);
        }
        //修改公告状态
        systemNotice.setNoticeState(AdminState.SYSTEM_NOTICE_PUBLISHED);
        systemNoticeMapper.updateById(systemNotice);
    }
    /**
     * 管理员删除系统公告
     * @param systemNoticeId
     * @param accountId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delSystemNotice(Integer systemNoticeId, Integer accountId) {
        //查询管理员账号是否存在 状态是否正常
        Result<AdminByAccountIdDTO> adminResult = adminClient.selAdminByAccountId(accountId);
        if (adminResult.getCode()!=200) {
            throw new NoticeException(adminResult.getCode(),adminResult.getMessage());
        }
        //查询当前公告是否存在
        SystemNotice systemNotice = systemNoticeMapper.selectById(systemNoticeId);
        if (systemNotice==null) {
            throw new NoticeException(NoticeExceptionCode.NOTICE_EXCEPTION_CODE_SYSTEMNOTICE_NOTEXITS);
        }
        //查询当前公告状态是否是删除状态
        if (systemNotice.getNoticeState()== AdminState.SYSTEM_NOTICE_DELETED) {
            throw new NoticeException(NoticeExceptionCode.NOTICE_EXCEPTION_CODE_NOTICESTATE_ERROR);
        }
        //修改公告状态
        systemNotice.setNoticeState(AdminState.SYSTEM_NOTICE_DELETED);
        systemNoticeMapper.updateById(systemNotice);
    }
}
